package org.esprit.ocm;

import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

//import org.cybera.ssh.SSH;

import com.xerox.amazonws.ec2.AttachmentInfo;
import com.xerox.amazonws.ec2.ImageDescription;
import com.xerox.amazonws.ec2.Jec2;
import com.xerox.amazonws.ec2.LaunchConfiguration;
import com.xerox.amazonws.ec2.ReservationDescription;
import com.xerox.amazonws.ec2.VolumeInfo;
import com.xerox.amazonws.ec2.ReservationDescription.Instance;

public class TypicaTutorial {
	public static final String	ATTACHED		= "attached";
	public static final String	AVAILABLE		= "available";

	private static final String	MOUNT_POINT		= "/volume1";
	private static final String	EUCALYPTUS_URL	= "192.168.100.200";

//	private Properties			props			= new Properties();
	private List<String>		owners			= new ArrayList<String>();
//	private String				sudo			= "";
	private Jec2				cloud			= null;

	public static void main(String[] args) throws Exception {
		TypicaTutorial typicaTutorial = new TypicaTutorial(args[0]);
		typicaTutorial.start(args[0]);
	}

	public TypicaTutorial(String arg) throws Exception {
//		props.load(TypicaTutorial.class.getClassLoader().getResourceAsStream(arg.trim() + ".properties"));
		owners.add("admin");
//		sudo = props.getProperty("vmAuth.sudo").trim();

		if ("euca".equals(arg)) {
			cloud = new Jec2("WKy3rMzOWPouVOxK1p3Ar1C2uRBwa2FBXnCw", "DO57RU23enPBIk8tfo0o2375UNuUosLnAlqDA", false, "192.168.100.200", 8773);
			cloud.setResourcePrefix("/services/Eucalyptus");
			cloud.setSignatureVersion(1);
		} else {
			cloud = new Jec2("WKy3rMzOWPouVOxK1p3Ar1C2uRBwa2FBXnCw", "DO57RU23enPBIk8tfo0o2375UNuUosLnAlqDA");
		}

//		System.out.println(arg + " " + props);
	}

	private void start(String arg) throws Exception {
		describeImages();
//		Instance instance = runInstance(arg);
//		AttachmentInfo volumeAttachmentInfo = createAttachAndMountVolume(instance);

//		doInterestingStuff(instance);

//		unmountDetachAndDeleteVolume(instance, volumeAttachmentInfo);
//		terminateInstance(instance);
	}

//	private void doInterestingStuff(Instance instance) throws Exception {
//		try {
//			SSH.runCommandOnInstance("ping -c 1 google.com", instance, props);
//		} catch (Exception e) {
//			// print the error but continue on so the instance gets cleaned up
//			e.printStackTrace();
//		}
//	}

	private void describeImages() throws Exception {
		List<ImageDescription> images = cloud.describeImagesByOwner(owners);

		for (ImageDescription image : images) {
			System.out.println(image.toString());
//			System.out.println("Image ID = " + image.getImageId() + ", Owner = " + image.getImageOwnerId());
		}
	}

	private Instance runInstance(String arg) throws Exception {
		LaunchConfiguration launchConfig = new LaunchConfiguration("emi-DDBB1069");
		launchConfig.setAvailabilityZone("192.168.100.200");
		launchConfig.setKeyName("emiraKey");
		launchConfig.setMinCount(1);
		launchConfig.setMaxCount(1);
		
		ReservationDescription reservationDescription = cloud.runInstances(launchConfig);
		Instance instance = reservationDescription.getInstances().get(0);
		String[] instances = new String[] { instance.getInstanceId() };

		// wait for the instance to start running
		do {
			instance = cloud.describeInstances(instances).get(0).getInstances().get(0);

			System.out.println("Run: Instance ID = " + instance.getInstanceId() + ", State = " + instance.getState());

			Thread.sleep(5000);
		} while (!instance.isRunning());

		System.out.println("Run: Instance ID = " + instance.getInstanceId() + ", Public DNS Name = " + instance.getDnsName()
				+ ", Private DNS Name = " + instance.getPrivateDnsName());

		// takes some time for SSH to start on the VMs so sleep for a bit or we
		// get a connection refused
		System.out.println("SSH: waiting for SSH on VM to start");
		Thread.sleep(30000);

		return instance;
	}

//	private AttachmentInfo createAttachAndMountVolume(Instance instance) throws Exception {
////		if (EUCALYPTUS_URL.equals(props.getProperty("cloud.URL"))) {
////			System.out.println("Create: Cannot create storage volumes on ECC :(");
////			return null;
////		}
//
//		VolumeInfo volumeInfo = cloud.createVolume("2", null, props.getProperty("launchConfig.availabilityZone").trim());
//		String[] volumes = new String[] { volumeInfo.getVolumeId() };
//
//		// wait for the volume to be created
//		do {
//			volumeInfo = cloud.describeVolumes(volumes).get(0);
//
//			System.out.println("Create: Volume ID = " + volumeInfo.getVolumeId() + ", State = " + volumeInfo.getStatus());
//
//			Thread.sleep(2000);
//		} while (!AVAILABLE.equals(volumeInfo.getStatus().toLowerCase()));
//
//		AttachmentInfo volumeAttachmentInfo = cloud.attachVolume(volumeInfo.getVolumeId(), instance.getInstanceId(),
//				props.getProperty("attachVolume.deviceName").trim());
//
//		// wait for the volume to be attached
//		do {
//			List<AttachmentInfo> volumeAttachmentInfos = cloud.describeVolumes(volumes).get(0).getAttachmentInfo();
//
//			volumeAttachmentInfo = volumeAttachmentInfos.get(0);
//
//			System.out.println("Attach: Volume ID = " + volumeAttachmentInfo.getVolumeId() + ", State = " + volumeAttachmentInfo.getStatus());
//
//			Thread.sleep(2000);
//		} while (!ATTACHED.equals(volumeAttachmentInfo.getStatus().toLowerCase()));
//
//		ArrayList<String> commandStrs = new ArrayList<String>();
//		commandStrs.add(sudo + " mkfs.ext3 -F -q " + props.getProperty("attachVolume.deviceName").trim());
//		commandStrs.add(sudo + " mkdir " + MOUNT_POINT);
//		commandStrs.add(sudo + " mount " + props.getProperty("attachVolume.deviceName").trim() + " " + MOUNT_POINT);
//
////		try {
////			SSH.runCommandsOnInstance(commandStrs, instance, props);
////		} catch (Exception e) {
////			// print the error but continue on so the instance gets cleaned up
////			e.printStackTrace();
////		}
//
//		return volumeAttachmentInfo;
//	}

//	private void unmountDetachAndDeleteVolume(Instance instance, AttachmentInfo volumeAttachmentInfo) throws Exception {
//		if (EUCALYPTUS_URL.equals(props.getProperty("cloud.URL"))) {
//			System.out.println("Delete: Cannot create storage volumes on ECC :(");
//			return;
//		}
//
////		try {
////			SSH.runCommandOnInstance(sudo + " umount " + MOUNT_POINT, instance, props);
////		} catch (Exception e) {
////			// print the error but continue on so the instance gets cleaned up
////			e.printStackTrace();
////		}
//
//		cloud.detachVolume(volumeAttachmentInfo.getVolumeId(), volumeAttachmentInfo.getInstanceId(), volumeAttachmentInfo.getDevice(), false);
//		String[] volumes = new String[] { volumeAttachmentInfo.getVolumeId() };
//		VolumeInfo volumeInfo;
//
//		// wait for the volume to detach
//		do {
//			volumeInfo = cloud.describeVolumes(volumes).get(0);
//
//			System.out.println("Detach: Volume ID = " + volumeInfo.getVolumeId() + ", State = " + volumeInfo.getStatus());
//
//			Thread.sleep(2000);
//		} while (!AVAILABLE.equals(volumeInfo.getStatus().toLowerCase()));
//
//		// don't wait for the volume to delete as this can take some time and
//		// it's not necessary to wait to move forward
//		cloud.deleteVolume(volumeAttachmentInfo.getVolumeId());
//
//		System.out.println("Delete: Volume ID = " + volumeInfo.getVolumeId() + ", State = deleting");
//	}

	private void terminateInstance(Instance instance) throws Exception {
		String[] instances = new String[] { instance.getInstanceId() };

		try {
			// don't wait for the instance to terminate as this can take some
			// time and it's not necessary to wait to move forward
			cloud.terminateInstances(instances);
		} catch (NullPointerException e) {
			// the call to terminate the instance goes through but it looks like
			// Eucalyptus returns a null value and typica chokes on it, ignore
			// it
			// see http://code.google.com/p/typica/issues/detail?id=105
		}

		System.out.println("Terminate: Instance ID = " + instance.getInstanceId() + ", State = shutting-down");
	}
}
